// editor：1.做一些初始化的工作，事件初始化，数据模型初始化，视图渲染 2.提供一些api供事件层调用

import { KeyboardEvent } from './event'
import { TextModel, SelectionModel } from './models'
import { InsertTextOperation, SetSelectionOperation, RemoveTextOperation } from './operations'
import { RenderView } from './view'
class Editor {
    // 文本数据模型
    textModel_;
    // 选区数据模型
    selectionModel_;
    // 视图
    view_;
    // 事件处理
    eventHandler;
    constructor(container) {
        this.container = container 
    }
    init () {
        // 初始化：事件
        this.eventHandler = new KeyboardEvent(this, this.container)
        // 初始化文本模型
        this.textModel_ = new TextModel()
        // 初始化选区模型
        this.selectionModel_ = new SelectionModel()
        // 初始化视图层
        this.view_ = new RenderView(this.textModel_, this.selectionModel_, this.container)
        // 触发监听事件
        this.eventHandler.addListeners()
    }

    getTextModel () {
        return this.textModel_
    }

    getSelectionModel () {
        return this.selectionModel_
    }

    // 调用原子操作
    apply (operation) {
        operation.apply(this);
    }

    /**
     * 
     * 插入文本：1.在光标处插入，2.在任意位置插入 3.在选区处插入：先删除选区，再在光标结束的位置插入.
     * 选区的删除分为：1.从左到右的删除 2.从右到左的删除
     */
    // 在光标处插入
    insertTextAtCursor (text) {
        console.log('text', text)
        const selection = this.selectionModel_.getSelection()
        let startIndex = selection.anchor
        // cursorIndex：光标的位置
        let cursorIndex;
        // 如果光标不重合,存在选区
        if (!this.selectionModel_.isCollapsed()) {
            const removeTextOperation = new RemoveTextOperation(selection.anchor, selection.focus)
            this.apply(removeTextOperation)
            if (this.selectionModel_.isBackward()) {
                startIndex = selection.focus;
            }
        }
        // 更新光标的位置
        cursorIndex = startIndex + text.length
        const insertTextOperation = new InsertTextOperation(text, startIndex);
        this.apply(insertTextOperation)
        // 设置选区
        this.setSelection(cursorIndex, cursorIndex)
    }

    /**
     * 在光标处删除: 1.从末尾删除，2.中间删除，3.选区删除
     * 选区的删除分为：1.从左到右的删除 2.从右到左的删除
     */
    deleteTextAtCursor() {
        const selection = this.selectionModel_.getSelection()
        let startIndex = selection.anchor
        if (!this.selectionModel_.isCollapsed()) {
            this.apply(new RemoveTextOperation(selection.anchor, selection.focus));
            if (this.selectionModel_.isBackward()) {
                startIndex = selection.focus;
            }
        } else if (selection.anchor > 0) {
            this.apply(new RemoveTextOperation(selection.anchor - 1, selection.focus));
            startIndex--
        }
        this.setSelection(startIndex, startIndex)
    }
    setSelection(anchor, focus) {
        const selectionOperaction = new SetSelectionOperation({anchor, focus})
        this.apply(selectionOperaction)
    }
}
export default Editor;